package com.yaxin.outsourcing.listener;

import cn.dev33.satoken.secure.BCrypt;
import com.yaxin.common.core.domain.entity.SysDept;
import com.yaxin.common.core.domain.entity.SysUser;
import com.yaxin.outsourcing.domain.HrMessage;
import com.yaxin.outsourcing.service.IAccessApplicationService;
import com.yaxin.system.mapper.SysUserMapper;
import com.yaxin.system.service.ISysDeptService;
import com.yaxin.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.List;
import org.springframework.amqp.core.Message;
import com.rabbitmq.client.Channel;



@Slf4j
@Component
public class HrListener {

    @Autowired
    private ISysDeptService deptService;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private IAccessApplicationService accessApplicationService;
    @Autowired
    private SysUserMapper userMapper;


    @RabbitListener(queues = "out_organizational_queue")
    public void handleSysDeptMessage(String messageJson, Message message, Channel channel) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

            // 关键：用 TypeReference 来反序列化泛型
            HrMessage<SysDept> sysDeptMessage = mapper.readValue(
                messageJson,
                new TypeReference<HrMessage<SysDept>>() {}
            );

            System.out.println("收到消息: " + sysDeptMessage);

            if(sysDeptMessage.getMsgMode().equals("I") || sysDeptMessage.getMsgMode().equals("U")){
                System.out.println("开始添加或新增");
                List<SysDept> data = sysDeptMessage.getData();
                if (data != null && !data.isEmpty()) {
                    deptService.insertOrUpdateDeptsBatchHighPerformance(data);
                    log.info("成功处理 {} 条部门数据", data.size());
                    channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                } else {
                    log.warn("部门信息消息为空或无数据");
                    channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                }
            }else if(sysDeptMessage.getMsgMode().equals("D")){
                List<SysDept> data = sysDeptMessage.getData();
                if (data != null && !data.isEmpty()) {
                    deptService.deleteDeptsBatchHighPerformance(data);
                    log.info("成功处理 {} 条部门数据", data.size());
                    channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                } else {
                    log.warn("部门信息消息为空或无数据");
                    channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                }
            }
        } catch (Exception e) {
            log.error("消息转换失败: {}", e.getMessage());
            log.error("原始消息内容: {}", messageJson);
            try {
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            } catch (Exception ex) {
                log.error("消息拒绝失败: {}", ex.getMessage(), ex);
            }
        }
    }

    @RabbitListener(queues = "out_personnel_queue")
    public void handleHrPersonMessage(String messageJson, Message message, Channel channel) {
        try {
            log.info("收到消息: " + messageJson);
            ObjectMapper mapper = new ObjectMapper();
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

            // 关键：用 TypeReference 来反序列化泛型
            HrMessage<SysUser> personMessage = mapper.readValue(
                messageJson,
                new TypeReference<HrMessage<SysUser>>() {
                }
            );

            if(personMessage.getMsgMode().equals("I") || personMessage.getMsgMode().equals("U")){
                List<SysUser> data = personMessage.getData();

                if (data != null && !data.isEmpty()) {
                    log.info("开始处理");
                    // 为没有密码的用户设置默认密码
                    data.forEach(user -> {
                        // 如果密码为空或null，则设置默认密码
                        if (user.getPassword() == null || user.getPassword().trim().isEmpty()) {
                            user.setPassword(BCrypt.hashpw("123456"));
                        }
                    });
                    // TODO: 调用你的人员处理服务，比如：
                    userService.insertOrUpdatePersonsBatchByUserName(data);
                    log.info("成功处理 {} 条人员数据", data.size());
                    channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                } else {
                    log.warn("人员信息消息为空或无数据");
                }
            }else if(personMessage.getMsgMode().equals("D")){
                List<SysUser> data = personMessage.getData();
                if (data != null && !data.isEmpty()) {
                    userMapper.deletePersonsBatchHighPerformance(data);
                    channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                } else {
                    log.warn("人员信息消息为空或无数据");
                    channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                }
            }
        } catch (Exception e) {
            log.error("人员消息转换失败: {}", e.getMessage(), e);
            log.error("原始消息内容: {}", messageJson);
            try {
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            } catch (Exception ex) {
                log.error("消息拒绝失败: {}", ex.getMessage(), ex);
            }
        }
    }

//    @RabbitListener(queues = "otback")
    public void handleOaBackMessage(String messageJson, Message message, Channel channel) {
        try {
            // 解析JSON消息
            ObjectMapper mapper = new ObjectMapper();
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

            // 方法1: 使用Map解析
            java.util.Map<String, Object> messageMap = mapper.readValue(messageJson, java.util.Map.class);

            // 提取appNo和code
            String appNo = (String) messageMap.get("appNo");
            Integer code = (Integer) messageMap.get("code");

            // 可以在这里根据code值进行不同的处理
            if (code != null) {
                switch (code) {
                    case 2:
                        log.info("审批通过，申请单号: {}", appNo);
                        accessApplicationService.updateStatusByAppNo(appNo, 2);
                        break;
                    case 3:
                        log.info("审批驳回，申请单号: {}", appNo);
                        accessApplicationService.updateStatusByAppNo(appNo, 3);
                        break;
                    default:
                        log.info("其他状态，申请单号: {}, 状态码: {}", appNo, code);
                }
            }

            // 手动确认消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);

        } catch (Exception e) {
            log.error("处理OA返回消息失败: {}", e.getMessage(), e);
            log.error("原始消息内容: {}", messageJson);
            try {
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            } catch (Exception ex) {
                log.error("消息拒绝失败: {}", ex.getMessage(), ex);
            }
        }
    }

    @RabbitListener(queues = "uat_person_queue")
    public void Test(String messageJson, Message message, Channel channel) {
        log.info("收到消息: {}", messageJson);
        try {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
